﻿using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.ComponentModel;
using System.Web;
using System.DirectoryServices;
using System.Security.Principal;
using System.Collections.Generic;
using System.IO;
using System.Security.AccessControl;
using Microsoft.Office.Server.UserProfiles;
using Microsoft.Office.Server;
using System.Configuration;

namespace Integrow.Webpart.NetworkShareList
{
    [Guid("50f610e6-725b-4436-b6dd-14c686f49617")]
    public class NetworkShareList : System.Web.UI.WebControls.WebParts.WebPart
    {
        private RadioButtonList linkList = null;
        Literal msg = new Literal();
        private string LDAPConnection = ConfigurationSettings.AppSettings["IntegrowLDAPConnection"];
        private string LDAPUserId = ConfigurationSettings.AppSettings["IntegrowLDAPUserId"];
        private string LDAPPassword = ConfigurationSettings.AppSettings["IntegrowLDAPPassword"];

        public NetworkShareList()
        {
            this.ExportMode = WebPartExportMode.All;
        }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("Network Share Site"),
        WebBrowsable(true),
        WebDescription("URL of the site that contains the network shares list.")]
        public Uri NetworkSharesSite { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("Network Share List"),
        WebBrowsable(true),
        WebDescription("Name of the list that contains the network shares.")]
        public string NetworkSharesList { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("UNC Path Column"),
        WebBrowsable(true),
        WebDescription("Column name in the Network Share list that contains the UNC path to the file share.")]
        public string ColUNCPath { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("UNC Description Column"),
        WebBrowsable(true),
        WebDescription("Column name that contains the description for the UNC path.")]
        public string ColUNCDescription { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("WebDAV URL Column"),
        WebBrowsable(true),
        WebDescription("Column name that contains the URL to use if using webdav.")]
        public string ColWebdavURL { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("Web Application URL Column"),
        WebBrowsable(true),
        WebDescription("Column name that contains the URL to the web application if used.")]
        public string ColWebAppURL { get; set; }

        [Personalizable(true),
        Category("Integrow"),
        WebPartStorage(Storage.Shared),
        WebDisplayName("Use Impersonation"),
        WebBrowsable(true),
        WebDescription("Use impersonation to determine directory security (check if kerberos is not used).")]
        public bool UseImpersonation { get; set; }

        protected override void CreateChildControls()
        {
            base.CreateChildControls();
            this.EnsureChildControls();

            this.linkList = new RadioButtonList();
            this.linkList.CssClass = "ms-RadioText";
            // this.linkList.AutoPostBack = true;
            this.linkList.RepeatDirection = RepeatDirection.Vertical;

            // Retrieve Home Directory from LDAP for current user.
            string login = System.Web.HttpContext.Current.User.Identity.Name;
            login = login.Remove(0, login.LastIndexOf("\\") + 1).ToLower();

            DirectoryEntry startEntry = null;

            try
            {
                if (UseImpersonation)
                {
                    // LDAP:// must be in uppercase.
                    if (LDAPConnection != null && LDAPConnection.Length > 0)
                    {
                        using (startEntry = new DirectoryEntry(LDAPConnection, LDAPUserId, LDAPPassword))
                        {
                            startEntry.AuthenticationType = AuthenticationTypes.Secure | AuthenticationTypes.ServerBind;

                            // Opens the connection
                            object obj = startEntry.NativeObject;

                            using (DirectorySearcher searcher = new DirectorySearcher())
                            {
                                using (WindowsImpersonationContext ctx = WindowsIdentity.Impersonate(IntPtr.Zero))
                                {
                                    searcher.SearchRoot = startEntry;
                                    searcher.Filter = string.Format("(samAccountName={0})", login);

                                    SearchResult result = searcher.FindOne();
                                    DirectoryEntry resultEntry = null;

                                    if (result != null)
                                    {
                                        resultEntry = result.GetDirectoryEntry();
                                        List<string> groupName = new List<string>();
                                        if (resultEntry.Properties["memberOf"].Count > 0)
                                        {

                                            foreach (string group in resultEntry.Properties["memberOf"])
                                            {
                                                groupName.Add(group.Substring(3, group.IndexOf(",") - 3));
                                            }
                                        }
                                        SPQuery query = new SPQuery();
                                        using (SPSite site = new SPSite(NetworkSharesSite.AbsoluteUri))
                                        {
                                            using (SPWeb web = site.OpenWeb())
                                            {
                                                SPList list = web.Lists[NetworkSharesList];
                                                // GetItems brings back everything with no where clause                
                                                SPListItemCollection items = list.GetItems(query);
                                                foreach (SPListItem item in items)
                                                {
                                                    String returnedItem = item[ColUNCPath].ToString();
                                                    // access directory info first using the path value from UNCPath
                                                    DirectoryInfo info = new DirectoryInfo(returnedItem);
                                                    DirectoryInfo[] directories = info.GetDirectories();
                                                    foreach (DirectoryInfo directory in directories)
                                                    {
                                                        DirectorySecurity sec = directory.GetAccessControl();
                                                        AuthorizationRuleCollection rules = sec.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount));
                                                        foreach (AuthorizationRule rule in rules)
                                                        {
                                                            if (rule.IdentityReference.Value != null && rule.IdentityReference.Value.IndexOf(@"\") > 0)
                                                            {
                                                                string identity = rule.IdentityReference.Value.Substring(rule.IdentityReference.Value.IndexOf(@"\") + 1);
                                                                if (groupName.Contains(identity) || login == identity.ToLower())
                                                                {
                                                                    AddUNC(item[ColUNCDescription].ToString() + " " + directory.Name, directory.FullName, item[ColWebdavURL].ToString(), item[ColWebAppURL].ToString());
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
                else
                {
                    SPQuery query = new SPQuery();
                    using (SPSite site = new SPSite(NetworkSharesSite.AbsoluteUri))
                    {
                        using (SPWeb web = site.OpenWeb())
                        {
                            SPList list = web.Lists[NetworkSharesList];
                            // GetItems brings back everything with no where clause                
                            SPListItemCollection items = list.GetItems(query);
                            foreach (SPListItem item in items)
                            {
                                String returnedItem = item[ColUNCPath].ToString();
                                // access directory info first using the path value from UNCPath
                                DirectoryInfo info = new DirectoryInfo(returnedItem);
                                DirectoryInfo[] directories = info.GetDirectories();
                                foreach (DirectoryInfo directory in directories)
                                {
                                    AddUNC(item[ColUNCDescription].ToString() + " " + directory.Name, directory.FullName, item[ColWebdavURL].ToString(), item[ColWebAppURL].ToString());
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                this.Controls.Clear();
                Literal msg = new Literal();
                msg.Text = "Unable to load the webpart contents correctly. Ensure that the parmeters have been entered correctly and the web.config has been updated." + ex.Message;
                this.Controls.Add(msg);
            }
            this.Controls.Add(linkList);
        }

        public string ConnectionValue
        {
            get
            {
                if (this.linkList == null)
                {
                    return "0";
                }
                return this.linkList.SelectedValue;
            }
        }


        private void AddUNC(string name, string unc, string webdavURL, string webAppURL)
        {
            ListItem item = new ListItem(name, unc);
            if (HttpContext.Current.Request.Browser.Browser == "IE")
            {
                item.Attributes.Add("OnClick", "document.getElementById('fileShareFrame').navigateFrame('" + webdavURL + "', 'fileShareFrame');");
            }
            else
            {
                item.Attributes.Add("OnClick", "document.getElementById('fileShareFrame').src='" + webAppURL + "';");
            }
            this.linkList.Items.Add(item);
        }
    }
}
